home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / rarp.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  6KB  |  225 lines

  1. /* Reverse Address Resolution Protocol (ARP) functions. Sits between IP and
  2.  * Level 2, mapping Level 2 addresses to IP.
  3.  */
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "proc.h"
  7. #include "timer.h"
  8. #include "iface.h"
  9. #include "socket.h"
  10. #include "ax25.h"
  11. #include "arp.h"
  12. #include "netuser.h"
  13. #include "cmdparse.h"
  14. #include "pktdrvr.h"
  15.  
  16. struct arp_stat Rarp_stat;
  17. static int Rwaiting = 0;        /* Semaphore used when waiting for a reply */
  18. /*static void arp_output __ARGS((struct iface *iface,int16 hardware,char *hwaddr,char *target));*/
  19. static int dorarpquery __ARGS((int argc,char *argv[],void *p));
  20. static void rarpstat __ARGS((void));
  21. static void rarp_output __ARGS((struct iface *iface,int16 hardware,char *hwaddr,char *target));
  22.  
  23. static struct cmds Rarpcmds[] = {
  24.     "query", dorarpquery, 0, 3,
  25. #ifdef fixed
  26.     "rarp query <interface> <ether addr|callsign> [<ether addr|callsign>]",
  27. #else
  28.     "rarp query <interface> <callsign> [<callsign>]",
  29. #endif
  30.     NULLCHAR
  31. };
  32.  
  33. int
  34. #ifdef PROTOTYPES
  35. dorarp(int argc,char **argv,void *p)
  36. #else
  37. dorarp(argc,argv,p)
  38. int argc;
  39. char *argv[];
  40. void *p;
  41. #endif
  42. {
  43.     if(argc < 2){
  44.         rarpstat();
  45.         return 0;
  46.     }
  47.     return subcmd(Rarpcmds,argc,argv,p);
  48. }
  49.  
  50. static int
  51. dorarpquery(argc,argv,p)
  52. int argc;
  53. char *argv[];
  54. void *p;
  55. {
  56.     struct iface *ifp;
  57.     char hwaddr[MAXHWALEN], qhwaddr[MAXHWALEN];
  58.     int16 hardware, t;
  59.     static char *errmsg = "Illegal hardware address\n";
  60.     if((ifp = if_lookup(argv[1])) == NULLIF){
  61.      tprintf(Badinterface,argv[1]);
  62.          return -1;
  63.     }
  64.     switch(ifp->iftype->type) {
  65.     case CL_AX25:
  66.          hardware = ARP_AX25;
  67.          break;
  68. #ifdef fixed
  69.     case CL_ETHERNET:
  70.          hardware = ARP_ETHER;
  71.          break;
  72.     default:
  73.          tputs("Only Ethernet and AX25 interfaces allowed\n");
  74. #else
  75.     default:
  76.          tputs("Only AX25 interfaces allowed\n");
  77. #endif
  78.          return -1;
  79.     }
  80.     if((*ifp->iftype->scan)(hwaddr,argv[2]) == -1) {
  81.          tputs(errmsg);
  82.          return -1;
  83.     }
  84.     if(argc > 3 && (*ifp->iftype->scan)(qhwaddr,argv[3]) == -1) {
  85.          tputs(errmsg);
  86.          return -1;
  87.     }
  88.     if(argc == 3)
  89.          memcpy(qhwaddr,hwaddr,(size_t)ifp->iftype->hwalen);
  90.     rarp_output(ifp,hardware,hwaddr,qhwaddr);
  91.  
  92.     t = Arp_type[hardware].pendtime;
  93.     ++Rwaiting;
  94.     tprintf("Trying...   %2d",t);
  95.     while(t--) {
  96.          alarm(1000L);
  97.          if(pwait(&Rwaiting) != EALARM) {
  98.           alarm(0);
  99.           --Rwaiting;
  100.           return 0;
  101.          }
  102.          tprintf("\b\b%2d",t);
  103.     }
  104.     tputs("\b\bTimeout.\n");
  105.     --Rwaiting;
  106.     return 0;
  107. }
  108.  
  109. /* Handle incoming RARP packets according to RFC 903.
  110.  */
  111. void
  112. rarp_input(iface,bp)
  113. struct iface *iface;
  114. struct mbuf *bp;
  115. {
  116.     struct arp rarp;
  117.     struct arp_type *at;
  118.     char shwaddr[MAXHWALEN];
  119.     
  120.     Rarp_stat.recv++;
  121.     if(ntoharp(&rarp,&bp) == -1)    /* Convert into host format */
  122.         return;
  123.     if(rarp.hardware >= NHWTYPES){
  124.         /* Unknown hardware type, ignore */
  125.         Rarp_stat.badtype++;
  126.         return;
  127.     }
  128.     at = &Arp_type[rarp.hardware];
  129.     if(rarp.protocol != at->iptype){
  130.         /* Unsupported protocol type, ignore */
  131.         Rarp_stat.badtype++;
  132.         return;
  133.     }
  134.     if((int16)uchar(rarp.hwalen) > MAXHWALEN || uchar(rarp.pralen) != sizeof(int32)){
  135.         /* Incorrect protocol addr length (different hw addr lengths
  136.          * are OK since AX.25 addresses can be of variable length)
  137.          */
  138.         Rarp_stat.badlen++;
  139.         return;
  140.     }
  141.     if(memcmp(rarp.shwaddr,at->bdcst,(size_t)at->hwalen) == 0){
  142.         /* This guy is trying to say he's got the broadcast address! */
  143.         Rarp_stat.badaddr++;
  144.         return;
  145.     }
  146.     if(rarp.opcode == REVARP_REQUEST) {
  147.         /* We are not a server, so we can only answer requests for a
  148.          * hardware address that is our own. But would be possible to
  149.          * use the ARP table to answer requests for someone elses
  150.          * IP address.
  151.          */
  152.         if(memcmp(rarp.thwaddr,iface->hwaddr,(size_t)at->hwalen) == 0) {
  153.             memcpy(shwaddr,rarp.shwaddr,(size_t)at->hwalen);
  154.             /* Mark the end of the sender's AX.25 address
  155.              * in case he didn't
  156.              */
  157.             if(rarp.hardware == ARP_AX25)
  158.                 rarp.thwaddr[uchar(rarp.hwalen)-1] |= E;
  159.             memcpy(rarp.shwaddr,iface->hwaddr,(size_t)at->hwalen);
  160.             rarp.sprotaddr = iface->addr;
  161.             rarp.tprotaddr = iface->addr;
  162.             rarp.opcode = REVARP_REPLY;
  163.  
  164.             if((bp = htonarp(&rarp)) == NULLBUF)
  165.                 return;
  166.  
  167.             if(iface->forw != NULLIF)
  168.                  (*iface->forw->output)(iface->forw,shwaddr,
  169.                     iface->forw->hwaddr,at->rarptype,bp);
  170.             else
  171.                  (*iface->output)(iface,shwaddr,
  172.                     iface->hwaddr,at->rarptype,bp);
  173.             Rarp_stat.inreq++;
  174.         }
  175.     } else {
  176.         Rarp_stat.replies++;
  177.         if(Rwaiting) {
  178.              psignal(&Rwaiting,1);
  179.              tprintf("\nRARP Reply: %s %s\n",
  180.                  (*at->format)(shwaddr,rarp.thwaddr),
  181.                  inet_ntoa(rarp.tprotaddr));
  182.         }
  183.     }
  184. }
  185.  
  186. /* Send a RARP request to target to resolve hardware address hwaddr */
  187. static void
  188. rarp_output(iface,hardware,hwaddr,target)
  189. struct iface *iface;
  190. int16 hardware;
  191. char *hwaddr;
  192. char *target;
  193. {
  194.     struct arp rarp;
  195.     struct mbuf *bp;
  196.     struct arp_type *at;
  197.  
  198.     at = &Arp_type[hardware];
  199.     if(iface->output == NULLFP((struct iface*,char*,char*,int16,struct mbuf*)))
  200.         return;
  201.     
  202.     rarp.hardware = hardware;
  203.     rarp.protocol = at->iptype;
  204.     rarp.hwalen = at->hwalen;
  205.     rarp.pralen = sizeof(int32);
  206.     rarp.opcode = REVARP_REQUEST;
  207.     memcpy(rarp.shwaddr,iface->hwaddr,(size_t)at->hwalen);
  208.     rarp.sprotaddr = 0;
  209.     memcpy(rarp.thwaddr,hwaddr,(size_t)at->hwalen);
  210.     rarp.tprotaddr = 0;
  211.     if((bp = htonarp(&rarp)) == NULLBUF)
  212.         return;
  213.     (*iface->output)(iface,target,
  214.         iface->hwaddr,at->rarptype,bp);
  215.     Rarp_stat.outreq++;
  216. }
  217.  
  218. static void
  219. rarpstat()
  220. {
  221.     tprintf("received %u badtype %u bogus addr %u reqst in %u replies %u reqst out %u\n",
  222.      Rarp_stat.recv,Rarp_stat.badtype,Rarp_stat.badaddr,Rarp_stat.inreq,
  223.      Rarp_stat.replies,Rarp_stat.outreq);
  224. }
  225.